package com.kedll.library.widget;

import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.PorterDuff;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.view.SupportMenuInflater;
import android.support.v7.view.menu.MenuBuilder;
import android.support.v7.view.menu.MenuItemImpl;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;

import com.kedll.library.widget.linearlistview.LinearListView;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by QiQi on 2017/4/5.
 */

public class BottomNavigationView extends LinearListView implements LinearListView.OnItemClickListener {
    private MenuBuilder mMenu;
    private MenuInflater mMenuInflater;
    private ColorStateList mItemIconTint;
    private ColorStateList mItemTextColor;
    private ColorStateList mItemMarkTextColor;
    private int mItemBackground;
    private int mItemMarkBackground;
    private PorterDuff.Mode mTintMode;

    private BottomNavigationAdapter adapter;

    private OnNavigationItemSelectedListener mListener;

    private int mActionButton = 0;

    public BottomNavigationView(Context context) {
        this(context, null);
    }

    public BottomNavigationView(Context context, AttributeSet attrs) {
        super(context, attrs);

        setGravity(Gravity.CENTER);
        setOrientation(LinearLayout.HORIZONTAL);
        mMenu = new BottomNavigationMenu(context);
        setOnItemClickListener(this);

        mMenu.setCallback(new MenuBuilder.Callback() {
            @Override
            public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
                return mListener != null && !mListener.onNavigationItemSelected(item);
            }

            @Override
            public void onMenuModeChange(MenuBuilder menu) {

            }
        });
    }


    public void setSelection(int position) {
        MenuItem menuItem = adapter.getItem(position).menuItem;
        menuItem.setChecked(true);
        adapter.notifyDataSetChanged();
        mActionButton = position;
    }

    public void initForMenu(int menuResId) {
        getMenuInflater().inflate(menuResId, mMenu);
        adapter = new BottomNavigationAdapter(this);
        List<MenuItemVo> menuItemVoList = new ArrayList<>();
        for (int i = 0; i < mMenu.size(); i++) {
            MenuItemVo menuItemVo = new MenuItemVo();
            mMenu.getItem(i).setCheckable(true);
            mMenu.getItem(i).setChecked(false);
            menuItemVo.menuItem = mMenu.getItem(i);
            menuItemVoList.add(menuItemVo);
        }
        mMenu.getItem(mActionButton).setChecked(true);
        setAdapter(adapter);

        adapter.addAll(menuItemVoList);
    }


    private MenuInflater getMenuInflater() {
        if (mMenuInflater == null) {
            mMenuInflater = new SupportMenuInflater(getContext());
        }
        return mMenuInflater;
    }


    public ColorStateList getItemIconTint() {
        return mItemIconTint;
    }

    public void setItemIconTint(ColorStateList mItemIconTint) {
        this.mItemIconTint = mItemIconTint;
    }

    public ColorStateList getItemTextColor() {
        return mItemTextColor;
    }

    public void setItemTextColor(ColorStateList mItemTextColor) {
        this.mItemTextColor = mItemTextColor;
    }

    public ColorStateList getItemMarkTextColor() {
        return mItemMarkTextColor;
    }

    public void setItemMarkTextColor(ColorStateList mItemMarkTextColor) {
        this.mItemMarkTextColor = mItemMarkTextColor;
    }

    public int getItemMarkBackground() {
        return mItemMarkBackground;
    }

    public void setItemMarkBackground(int mItemMarkBackground) {
        this.mItemMarkBackground = mItemMarkBackground;
    }

    public PorterDuff.Mode getTintMode() {
        return mTintMode;
    }

    public void setTintMode(PorterDuff.Mode mTintMode) {
        this.mTintMode = mTintMode;
    }

    public void setItemBackground(int mItemBackground) {
        this.mItemBackground = mItemBackground;
    }

    public int getItemBackground() {
        return mItemBackground;
    }

    @Override
    public BottomNavigationAdapter getAdapter() {
        return adapter;
    }

    /**
     * Set a listener that will be notified when a bottom navigation item is selected.
     *
     * @param listener The listener to notify
     */
    public void setOnNavigationItemSelectedListener(
            @Nullable OnNavigationItemSelectedListener listener) {
        mListener = listener;
    }

    /**
     * Callback method to be invoked when an item in this LinearListView has
     * been clicked.
     * <p>
     * Implementers can call getItemAtPosition(position) if they need to
     * access the data associated with the selected item.
     *
     * @param parent   The LinearListView where the click happened.
     * @param view     The view within the LinearListView that was clicked (this
     *                 will be a view provided by the adapter)
     * @param position The position of the view in the adapter.
     * @param id
     */
    @Override
    public void onItemClick(LinearListView parent, View view, int position, long id) {
        if (mActionButton == position) {
            return;
        }
        final MenuItem menuItem = adapter.getItem(position).menuItem;
        if (!mMenu.performItemAction(menuItem, 0)) {
            menuItem.setChecked(true);
            adapter.notifyDataSetChanged();
        }
        mActionButton = position;
    }

    /**
     * Listener for handling events on bottom navigation items.
     */
    public interface OnNavigationItemSelectedListener {

        /**
         * Called when an item in the bottom navigation menu is selected.
         *
         * @param item The selected item
         * @return true to display the item as the selected item and false if the item should not
         * be selected. Consider setting non-selectable items as disabled preemptively to
         * make them appear non-interactive.
         */
        boolean onNavigationItemSelected(@NonNull MenuItem item);
    }

    public static final class MenuItemVo {
        public int count = 0;
        public MenuItem menuItem;
    }

    private static class BottomNavigationAdapter extends ArrayAdapter<MenuItemVo> {
        private BottomNavigationView navigationView;

        public BottomNavigationAdapter(BottomNavigationView navigationView) {
            super(navigationView.getContext(), 0);
            this.navigationView = navigationView;
        }


        @NonNull
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            BottomNavigationItem navigationItem;
            if (convertView == null) {
                navigationItem = new BottomNavigationItem(navigationView.getContext());
                LayoutParams params = new LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT);
                params.weight = 1;
                navigationItem.setLayoutParams(params);
            } else {
                navigationItem = (BottomNavigationItem) convertView;
            }

            final MenuItemVo menuItem = getItem(position);
            navigationItem.setTextColor(navigationView.getItemTextColor());
            navigationItem.setIconTintList(navigationView.getItemIconTint());
            navigationItem.setMarkTextColor(navigationView.getItemMarkTextColor());
            navigationItem.setMarkBackground(navigationView.getItemMarkBackground());
            navigationItem.setTintMode(navigationView.getTintMode());
            navigationItem.setItemBackground(navigationView.getItemBackground());
            navigationItem.initialize((MenuItemImpl) menuItem.menuItem, 0);
            navigationItem.setMark(menuItem.count);

            return navigationItem;
        }
    }
}

